
//leetcode submit region begin(Prohibit modification and deletion)
class Solution {

    /**
     * 第一遍
     * @param s
     * @return
     */
//    public int lengthOfLongestSubstring(String s) {
//        // 记录字符上一次出现的位置
//        int[] last = new int[128];
//        for(int i = 0; i < 128; i++) {
//            last[i] = -1;
//        }
//        int n = s.length();
//
//        // 最长无重复子串长度
//        int res = 0;
//        // 窗口开始位置
//        int start = 0;
//        for(int i = 0; i < n; i++) {
//            int index = s.charAt(i);
//            start = Math.max(start, last[index] + 1);
//            res   = Math.max(res, i - start + 1);
//            last[index] = i;
//        }
//        return res;
//    }




    /**
     * 第二遍
     * @param s
     * @return
     */
    public int lengthOfLongestSubstring(String s) {
        // 使用包装类可以避免在调用getOrDefault方法时出现空指针异常。
        Map<Character, Integer> window = new HashMap();

        int slow = 0, fast = 0;
        // 记录无重复子串长度
        int res = 0;
        while (fast < s.length()) {
            char c = s.charAt(fast);
            fast++;
            // 进行窗口内数据更新
            window.put(c, window.getOrDefault(c, 0) + 1);
            // 判断左侧窗口是否要收缩
            while (window.get(c) > 1) {
                char d = s.charAt(slow);
                slow++;
                // 进行窗口内数据更新
                window.put(d, window.get(d) - 1);
            }
            // 更新
            res = Math.max(res, fast - slow);
        }
        return res;
    }
}
//leetcode submit region end(Prohibit modification and deletion)
